#pragma once

#include <string>
#include <vector>
#include <variant>
#include <rclcpp/rclcpp.hpp>

namespace monitor {

template<typename T>
struct Param {
    std::string name;
    T default_value;
    std::string description;

    Param(const std::string& n, const T& def, const std::string& desc)
        : name(n), default_value(def), description(desc) {}
};

using ParamVariant = std::variant<
    Param<int>,
    Param<double>,
    Param<bool>,
    Param<std::string>
>;

/**
 * @brief 节点参数管理类
 */
class NodeParameters {
public:
    // 所有参数存储在一个容器中
    static inline const std::vector<ParamVariant> parameters = {
        Param<bool>("simulation_mode", false, ""),
        Param<bool>("use_modemonitor", true, ""),
        Param<bool>("use_internal_safty_moudle", true, ""),
        Param<bool>("use_sysmonitor", true, ""),
        Param<bool>("use_nodemonitor", true, ""),
        Param<double>("event_manager_cycle", 0.03, ""),
        Param<double>("mode_monitor_cycle", 1.0, ""),
        Param<double>("safety_monitor_cycle", 0.1, ""),
        Param<double>("system_monitor_cycle", 5.0, ""),
        Param<double>("node_monitor_cycle", 1.0, "SafetyMonitor 参数"),
        Param<double>("safety_monitor.delay", 5.0, ""),
        Param<std::string>("safety_monitor.odom_topic", "/odom", ""),
        Param<int>("safety_monitor.EStopMode", 0, "CURVE_NONE"),
        Param<int>("safety_monitor.ObsAvoidanceStopMode", 2, "CURVE_SPTA"),
        Param<int>("safety_monitor.BumperStopMode", 0, "CURVE_NONE"),
        Param<double>("safety_monitor.StopSpeedThreshold", 0.15, ""),
        Param<double>("safety_monitor.StepSpeed", 0.1, ""),
        Param<double>("safety_monitor.SpeedMax", 1.5, ""),
        Param<double>("safety_monitor.SpeedMin", -1.0, ""),
        Param<double>("safety_monitor.Flexible", 5.2, "ModeMonitor 参数"),
        Param<int>("mode_monitor.mode", 0, "AGV mode"),
        Param<bool>("mode_monitor.shielded_peripherals", false, "是否忽略外设"),
        Param<double>("mode_monitor.delay", 600.0, "延时时间，范围 0-600"),
        Param<double>("mode_monitor.key_press_delay", 2.0, "按键延时"),
        Param<int>("AGVParam.agv_navigation_type", 0, "导航模式"),
        Param<std::string>("AGVParam.current_floor", "unkown", "楼层名称"),
        Param<int>("AGVParam.floor_num", 1, "楼层")
    };

    /**
     * @brief 在节点上声明所有参数
     */
    static void declareParameters(rclcpp::Node* node) {
        for (const auto& param_variant : parameters) {
            std::visit([node](const auto& param) {
                declareParam(node, param);
            }, param_variant);
        }
    }

private:
    template<typename T>
    static void declareParam(rclcpp::Node* node, const Param<T>& param) {
        rcl_interfaces::msg::ParameterDescriptor descriptor;
        descriptor.description = param.description;
        node->declare_parameter(param.name, param.default_value, descriptor);
    }
};
} // namespace 